// Metgine/Core/ResourceManager.h
//
// Copyright 2011 Phillip Stephens
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
//
// Linking this library statically or dynamically with other modules is
// making a combined work based on this library.  Thus, the terms and
// conditions of the GNU General Public License cover the whole
// combination.

#ifndef __RESOURCEMANAGER_H__
#define __RESOURCEMANAGER_H__

#include <map>
#include <queue>
#include <string>

#include <SFML/System.hpp>

#include <Metgine/Core/Singleton.h>
#include <Metgine/Core/Resource.h>
#include <Metgine/Core/ImageResource.h>
#include <Metgine/Core/SoundResource.h>
#include <Metgine/Core/FontResource.h>
#include <Metgine/Core/TextResource.h>
#include <Metgine/Core/Log.h>
#include <Metgine/Core/Thread.h>

namespace Metgine
{
namespace Core
{

void DoWork(void*);

struct QueuedResource
{

    ResourceType::ResourceType    type;            // Type of the resource
    std::string                   name;            // Internal name of the resource
    std::string                   path;            // Path to the resource file

};

class ResourceLoaderThread : public Thread
{
private:
    void Run();
};

class METGINE_API ResourceManager : public Singleton<ResourceManager>
{
friend class Singleton<ResourceManager>;
friend class ResourceLoaderThread;
private:

    std::map<std::string, Resource*>      m_resources;                // Map of resource names to resource pointers
    std::queue<QueuedResource>            m_loadQueue;                // Queue of resources waiting to be loaded
    bool                                  m_loading;
    ResourceLoaderThread*                 m_loadThread;

    // Constructor
    ResourceManager();

    // Destructor
    ~ResourceManager();
public:

    // Gets a resource by name
    Resource* GetResource(const std::string& name);
    ImageResource* GetImage(const std::string& name);
    SoundResource* GetSound(const std::string& name);
    FontResource* GetFont(const std::string& name);
    TextResource* GetText(const std::string& name);

    // Adds a resource to the manager - takes ownership of the resource instance
    void AddResource(const std::string& name, Resource* resource);

    // Queues a resource for loading
    void QueueResource(const std::string& name, ResourceType::ResourceType type, const std::string& path);

    // Loads all queued resources
    void LoadQueuedResources();

    // Processes the load queue (works on a seperate thread)
    void ProcessQueue();

    // Frees memory associated with a resource
    void FreeResource(const std::string& name);

    // Frees all currently loaded resources
    void FreeAllResources();

    // Gets the number of resources currently loaded
    int NumResources() const;

    // Returns true if the resourcemanager is currently processing the load queue
    bool IsLoading() const;

};
}; // Core
}; // Metgine

#endif // RESOURCEMANAGER_H
